package com.durian.app.lifecycle.apt;

import com.durian.app.lifecycle.annotation.LifeCycleConfig;

import java.util.List;


/**
 * 说明：RoutePathCreator
 * <p/>
 * 作者：fanly
 * <p/>
 * 类型：Class
 * <p/>
 * 时间：2019-06-12 18:07
 * <p/>
 * 版本：version 1.0
 */
public class RouterCreator {

    private List<PathBuilder> pathList;
    private List<ServiceBuilder> serviceList;
    private String className;

    public static class ServiceBuilder{
        private String value;
        private String methodName;
        private String filedName;
        private String serviceName;

        public ServiceBuilder setServiceName(String serviceName){
            this.serviceName = serviceName;
            return this;
        }

        public ServiceBuilder setValue(String value) {
            this.value = value;
            return this;
        }
        public ServiceBuilder setMethodName(String methodName) {
            this.methodName = methodName;
            return this;
        }

        public ServiceBuilder setFiledName(String filedName) {
            this.filedName = filedName;
            return this;
        }

        public String getMethodName() {
            if (RouterProcessor.isNotEmpty(methodName)){
                return methodName;
            }else {
                String []strs = filedName.split("_");
                String name = "get%sService";
                String method = "";
                if (strs != null && strs.length > 0){
                    for (String s:strs){
                        if (RouterProcessor.isNotEmpty(s)){
                            method += ((s.charAt(0)+"").toUpperCase()+s.substring(1).toLowerCase());
                        }
                    }
                }
                return String.format(name,method);
            }
        }

        public String getMethodContent(){
            StringBuilder sb = new StringBuilder();
            sb.append(String.format("%s t = (%s)EasyRouter.build(\"%s\").navigation();\n",serviceName,serviceName,value));
            sb.append("        if (t == null){\n");
            sb.append("            return t;\n");
            sb.append("        }\n");
            sb.append("        if (!(t instanceof IEasyProvider)){\n");
            sb.append("            throw new RuntimeException(\"must extend IEasyProvider!!!\");\n");
            sb.append("        }\n");
            sb.append("        t.prepare();\n");
            sb.append("        return t;\n");
            return sb.toString();
        }
    }

    public static class PathBuilder{
        private String value;
        private String fragment;
        private int extras;
        private String methodName;
        private String filedName;
        private String []params;
        private String []transfer;

        public PathBuilder setTransfer(String[] transfer){
            this.transfer = transfer;
            return this;
        }

        public PathBuilder setValue(String value) {
            this.value = value;
            return this;
        }

        public PathBuilder setFragment(String fragment) {
            this.fragment = fragment;
            return this;
        }

        public PathBuilder setExtras(int extras) {
            this.extras = extras;
            return this;
        }

        public PathBuilder setMethodName(String methodName) {
            this.methodName = methodName;
            return this;
        }

        public PathBuilder setFiledName(String filedName) {
            this.filedName = filedName;
            return this;
        }

        public PathBuilder setParams(String[] params) {
            this.params = params;
            return this;
        }

        public String getParamsValue(){
            StringBuilder sb = new StringBuilder();
            for (String s:params){
                if (RouterProcessor.isNotEmpty(s)){
                    sb.append("String ").append(s).append(",");
                }
            }
            return sb.deleteCharAt(sb.length()-1).toString();
        }

        public boolean hasParams(){
            boolean has = false;
            if (params != null && params.length > 0){
                for (String s:params){
                    if (RouterProcessor.isNotEmpty(s)){
                        has = true;
                        break;
                    }
                }
            }
            return has;
        }

        public String getMethodName() {
            if (RouterProcessor.isNotEmpty(methodName)){
                return methodName;
            }else {
                String []strs = filedName.split("_");
                String method = "";
                if (strs != null && strs.length > 0){
                    int i = 0,len = strs.length;
                    for (;i < len;i++){
                        if (!RouterProcessor.isNotEmpty(strs[i])){
                            continue;
                        }
                        if (i == 0){
                            method +=strs[i].toLowerCase();
                        }else {
                            method += ((strs[i].charAt(0)+"").toUpperCase()+strs[i].substring(1).toLowerCase());
                        }
                    }
                }
                return method;
            }
        }

        public String getMethodContent(boolean useParams){
            StringBuilder sb = new StringBuilder();
            sb.append("return ")
                    .append("EasyRouter.build(\"")
                    .append(value)
                    .append("\")");
            if (RouterProcessor.isNotEmpty(fragment)){
                sb.append(".withString(").append("EasyRouter.KEY_FRAGMENT,").append("\""+fragment+"\")");
            }
            sb.append(".withInt(").append("EasyRouter.KEY_EXTRA,").append(extras+")");
            if (transfer != null && transfer.length > 0){
                int i = 0,size = transfer.length;
                for (;i < size;i+=2){
                    if (RouterProcessor.isNotEmpty(transfer[i]) && i + 1 < size && RouterProcessor.isNotEmpty(transfer[i+1])){
                        sb.append(".withString(\"").append(transfer[i]+"\",").append("\"").append(transfer[i+1]+"\")");
                    }
                }
            }
            if (useParams && params != null){
                for (String s:params){
                    if (RouterProcessor.isNotEmpty(s)){
                        sb.append(".withString(\"").append(s+"\",").append(s+")");
                    }
                }
            }
            sb.append(";\n");
            return sb.toString();
        }
    }

    public RouterCreator(String className,List<PathBuilder> path,List<ServiceBuilder> service) {
        this.className = className;
        pathList = path;
        serviceList = service;
    }

    /**
     * 获取要生成的代理类的完整类名
     *
     * @return
     */
    public String getProxyClassFullName() {
        String name = LifeCycleConfig.PROXY_ROUTER_CLASS_PACKAGE_NAME + "."+ className;
        return name;
    }

    /**
     * 生成java代码
     */
    public String generateJavaCode() {
        StringBuilder sb = new StringBuilder();
        //设置包名
        sb.append("package ").append(LifeCycleConfig.PROXY_ROUTER_CLASS_PACKAGE_NAME).append(";\n\n");

        sb.append("import com.durian.base.frame.easyrouter.EasyRouter;\n\n");

        sb.append("import com.durian.base.frame.easyrouter.IEasyProvider;\n\n");

        sb.append("public final class ").append(className).append(" {\n\n");

        //构造函数
        sb.append("  private ").append(className).append("() {}\n\n");

        if (!pathList.isEmpty()){
            for (PathBuilder builder:pathList){
                sb.append(generatePathMethod(builder));
            }
        }

        if (!serviceList.isEmpty()){
            for (ServiceBuilder builder:serviceList){
                sb.append(generateServiceMethod(builder));
            }
        }

        sb.append("\n}");
        return sb.toString();
    }

    private String generatePathMethod(PathBuilder builder){
        StringBuilder sb = new StringBuilder();
        if (builder.hasParams()){
            sb.append("    public static EasyRouter ").append(builder.getMethodName()).append("("+builder.getParamsValue()+"){\n");
            sb.append("        ").append(builder.getMethodContent(true));
            sb.append("    }\n\n");
        }else {
            sb.append("    public static EasyRouter ").append(builder.getMethodName()).append("(){\n");
            sb.append("        ").append(builder.getMethodContent(false));
            sb.append("    }\n\n");
        }
        return sb.toString();
    }

    private String generateServiceMethod(ServiceBuilder builder){
        StringBuilder sb = new StringBuilder();
        sb.append("    public final static ").append(builder.serviceName).append(" ").append(builder.getMethodName()).append("(){\n");
        sb.append("        ").append(builder.getMethodContent());
        sb.append("    }\n\n");
        return sb.toString();
    }

}
